"""
集成的产品序列化器 - 支持在产品创建/编辑时直接管理变体
"""

from rest_framework import serializers
from pecco_site.models import (
    Product, ProductTranslation, ProductVariant, ProductVariantImage,
    ProductOption, ProductOptionValue, ProductOptionTranslation,
    ProductOptionValueTranslation, ProductSpecification, Category
)
from django.db import transaction
from decimal import Decimal
from django.core.files import File
from django.core.files.storage import default_storage
from django.conf import settings
from urllib.parse import urlparse
import os


class VariantOptionValueSerializer(serializers.Serializer):
    """变体选项值序列化器（用于创建/更新）"""
    option_type = serializers.CharField(help_text='选项类型，如 size, color')
    value = serializers.CharField(help_text='选项值，如 Large, Red')
    color_code = serializers.CharField(required=False, allow_blank=True, allow_null=True, 
                                      help_text='颜色代码（仅颜色选项需要）')
    translations = serializers.DictField(required=False, help_text='翻译，格式：{"en": "Large", "zh": "大号"}')


class VariantImageUploadSerializer(serializers.Serializer):
    """变体图片上传序列化器"""
    image = serializers.ImageField()
    sort_order = serializers.IntegerField(default=0)
    is_primary = serializers.BooleanField(default=False)


class VariantImageInputSerializer(serializers.Serializer):
    """变体图片数据序列化器"""
    url = serializers.CharField(required=False, allow_blank=True)
    path = serializers.CharField(required=False, allow_blank=True)
    sort_order = serializers.IntegerField(required=False)
    is_primary = serializers.BooleanField(required=False)


class VariantSpecificationInputSerializer(serializers.Serializer):
    """变体规格序列化器"""
    key = serializers.CharField(required=False, allow_blank=True)
    value = serializers.CharField(required=False, allow_blank=True)
    sort_order = serializers.IntegerField(required=False)
    is_active = serializers.BooleanField(required=False)


class ProductVariantInputSerializer(serializers.Serializer):
    """产品变体输入序列化器（用于创建/更新产品时的变体数据）"""
    id = serializers.IntegerField(required=False, allow_null=True, help_text='变体ID（更新时需要）')
    sku = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    option_values = serializers.ListField(
        child=VariantOptionValueSerializer(),
        help_text='选项值列表'
    )
    price = serializers.DecimalField(max_digits=10, decimal_places=2, required=True)
    stock = serializers.IntegerField(required=True, min_value=0)
    product_details = serializers.CharField(required=False, allow_blank=True, allow_null=True,
                                           help_text='产品详情（HTML）')
    is_active = serializers.BooleanField(default=True)
    sort_order = serializers.IntegerField(default=0)
    # 兼容旧数据：图片URL列表
    image_urls = serializers.ListField(
        child=serializers.CharField(),
        required=False,
        help_text='图片URL列表'
    )
    images = VariantImageInputSerializer(many=True, required=False)
    specifications = VariantSpecificationInputSerializer(many=True, required=False)


class ProductIntegratedSerializer(serializers.ModelSerializer):
    """
    集成的产品序列化器 - 支持在创建/编辑时直接管理变体
    """
    # 分类（支持多选）
    category_slug = serializers.SlugField(write_only=True, required=False, help_text='单个分类slug（兼容旧版）')
    category_slugs = serializers.ListField(
        child=serializers.SlugField(),
        write_only=True,
        required=False,
        help_text='分类slug列表（支持多选）'
    )
    category = serializers.SerializerMethodField(read_only=True)
    categories_data = serializers.SerializerMethodField(read_only=True)

    # 翻译
    cover_image = serializers.ImageField(required=False, allow_null=True)
    hover_image = serializers.ImageField(required=False, allow_null=True)
    translations = serializers.DictField(
        child=serializers.DictField(),
        write_only=True,
        help_text='翻译数据，格式：{"en": {"name": "...", "short_desc": "...", "rich_desc": "..."}, "zh": {...}}'
    )
    translations_data = serializers.SerializerMethodField(read_only=True)

    # 图片 URL
    cover_image_url = serializers.SerializerMethodField(read_only=True)
    hover_image_url = serializers.SerializerMethodField(read_only=True)

    # 变体
    variants = ProductVariantInputSerializer(many=True, write_only=True, required=False)
    variants_data = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Product
        fields = [
            'id', 'category_slug', 'category_slugs', 'category', 'categories_data',
            'cover_image', 'hover_image', 'cover_image_url', 'hover_image_url',
            'is_active', 'sort_order', 'usage', 'tag_new', 'tag_hot', 'tag_featured',
            'created_at', 'updated_at', 'translations', 'translations_data',
            'variants', 'variants_data'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']

    def validate(self, attrs):
        if self.instance is None:
            cover = attrs.get('cover_image')
            if not cover:
                raise serializers.ValidationError({'cover_image': '请上传封面图'})
        return super().validate(attrs)

    def get_category(self, obj):
        """获取分类信息（兼容旧版，返回第一个分类）"""
        first_cat = obj.categories.first()
        if first_cat:
            return {
                'id': first_cat.id,
                'slug': first_cat.slug
            }
        return None

    def get_categories_data(self, obj):
        """获取所有分类信息"""
        categories_data = []
        for cat in obj.categories.all():
            # 获取中文翻译名称
            trans = cat.translations.filter(locale='zh').first()
            name = trans.name if trans else cat.slug
            categories_data.append({
                'id': cat.id,
                'slug': cat.slug,
                'name': name
            })
        return categories_data
    
    def get_cover_image_url(self, obj):
        if obj.cover_image:
            request = self.context.get('request')
            if request:
                return request.build_absolute_uri(obj.cover_image.url)
            return obj.cover_image.url
        return None
    
    def get_hover_image_url(self, obj):
        if obj.hover_image:
            request = self.context.get('request')
            if request:
                return request.build_absolute_uri(obj.hover_image.url)
            return obj.hover_image.url
        return None
    
    def get_translations_data(self, obj):
        """获取所有翻译"""
        result = {}
        for trans in obj.translations.all():
            result[trans.locale] = {
                'name': trans.name,
                'short_desc': trans.short_desc,
                'rich_desc': trans.rich_desc,
                'default_product_details': trans.default_product_details,
                'general_specifications': trans.general_specifications
            }
        return result
    
    def get_variants_data(self, obj):
        """获取所有变体数据"""
        variants = []
        request = self.context.get('request')
        
        for variant in obj.variants.all():
            # 获取选项值
            option_values = []
            for opt_val in variant.option_values.all():
                # 获取翻译
                translations = {}
                for trans in opt_val.translations.all():
                    translations[trans.locale] = trans.value
                
                option_values.append({
                    'id': opt_val.id,
                    'option_type': opt_val.option.option_type,
                    'value': opt_val.value,
                    'color_code': opt_val.color_code,
                    'translations': translations
                })
            
            # 获取图片
            images = []
            for img in variant.images.all():
                image_url = None
                if img.image:
                    if request:
                        image_url = request.build_absolute_uri(img.image.url)
                    else:
                        image_url = img.image.url
                
                images.append({
                    'id': img.id,
                    'url': image_url,
                    'path': img.image.name,
                    'sort_order': img.sort_order,
                    'is_primary': img.is_primary
                })

            specifications = []
            for spec in variant.specifications.filter(is_active=True).order_by('sort_order'):
                specifications.append({
                    'id': spec.id,
                    'key': spec.spec_key,
                    'value': spec.spec_value,
                    'sort_order': spec.sort_order,
                    'is_active': spec.is_active
                })
            
            variants.append({
                'id': variant.id,
                'sku': variant.sku,
                'option_values': option_values,
                'price': str(variant.price),
                'stock': variant.stock,
                'product_details': variant.product_details,
                'is_active': variant.is_active,
                'sort_order': variant.sort_order,
                'images': images,
                'specifications': specifications
            })
        
        return variants
    
    @transaction.atomic
    def create(self, validated_data):
        """创建产品及其变体"""
        # 获取分类（支持单个或多个）
        category_slug = validated_data.pop('category_slug', None)
        category_slugs = validated_data.pop('category_slugs', None)
        translations_data = validated_data.pop('translations', {})
        variants_data = validated_data.pop('variants', [])

        # 创建产品
        product = Product.objects.create(**validated_data)

        # 设置分类
        slugs_to_use = category_slugs if category_slugs else ([category_slug] if category_slug else [])
        if not slugs_to_use:
            raise serializers.ValidationError('请至少选择一个分类')

        categories = Category.objects.filter(slug__in=slugs_to_use, is_active=True)
        if categories.count() != len(slugs_to_use):
            raise serializers.ValidationError('部分分类不存在或未激活')

        product.categories.set(categories)

        # 创建翻译
        for locale, trans_data in translations_data.items():
            ProductTranslation.objects.create(
                product=product,
                locale=locale,
                **trans_data
            )

        # 创建变体
        self._create_variants(product, variants_data)

        return product
    
    @transaction.atomic
    def update(self, instance, validated_data):
        """更新产品及其变体"""
        category_slug = validated_data.pop('category_slug', None)
        category_slugs = validated_data.pop('category_slugs', None)
        translations_data = validated_data.pop('translations', None)
        variants_data = validated_data.pop('variants', None)

        # 更新基本信息
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()

        # 更新分类
        slugs_to_use = category_slugs if category_slugs else ([category_slug] if category_slug else None)
        if slugs_to_use:
            categories = Category.objects.filter(slug__in=slugs_to_use, is_active=True)
            if categories.count() != len(slugs_to_use):
                raise serializers.ValidationError('部分分类不存在或未激活')
            instance.categories.set(categories)
        
        # 更新翻译
        if translations_data is not None:
            instance.translations.all().delete()
            for locale, trans_data in translations_data.items():
                ProductTranslation.objects.create(
                    product=instance,
                    locale=locale,
                    **trans_data
                )
        
        # 更新变体
        if variants_data is not None:
            # 删除旧变体
            instance.variants.all().delete()
            # 创建新变体
            self._create_variants(instance, variants_data)
        
        return instance
    
    def _create_variants(self, product, variants_data):
        """创建变体的辅助方法"""
        for variant_data in variants_data:
            option_values_data = variant_data.pop('option_values', [])
            images_data = variant_data.pop('images', None)
            if images_data is None:
                images_data = variant_data.pop('image_urls', [])
            specifications_data = variant_data.pop('specifications', [])
            variant_data.pop('id', None)  # 移除ID（如果有）
            
            # 创建变体
            variant = ProductVariant.objects.create(
                product=product,
                **variant_data
            )
            
            # 处理选项值
            option_value_ids = []
            for opt_val_data in option_values_data:
                option_value = self._get_or_create_option_value(opt_val_data)
                option_value_ids.append(option_value.id)
            
            # 设置选项值
            variant.option_values.set(option_value_ids)
            self._create_variant_images(variant, images_data)
            self._create_variant_specifications(product, variant, specifications_data)

    def _create_variant_images(self, variant, images_data):
        """根据提交的数据创建变体图片"""
        if not images_data:
            return

        if isinstance(images_data, list):
            entries = images_data
        else:
            entries = []

        for index, entry in enumerate(entries):
            if isinstance(entry, str):
                entry = {'url': entry}
            elif not isinstance(entry, dict):
                continue

            path = entry.get('path') or ''
            url = entry.get('url') or ''
            sort_order = entry.get('sort_order', index)
            is_primary = entry.get('is_primary', False)

            if not path and url:
                parsed = urlparse(url)
                media_url = settings.MEDIA_URL or ''
                if parsed.path.startswith(media_url):
                    path = parsed.path[len(media_url):]
                else:
                    path = parsed.path.lstrip('/')

            if not path:
                continue

            if not default_storage.exists(path):
                continue

            variant_image = ProductVariantImage(
                variant=variant,
                sort_order=sort_order,
                is_primary=is_primary
            )

            if path.startswith('temp_variants/'):
                filename = os.path.basename(path)
                target_name = os.path.join('product_variants', filename)
                with default_storage.open(path, 'rb') as f:
                    image_file = File(f, name=filename)
                    variant_image.image.save(target_name, image_file, save=True)
                default_storage.delete(path)
            else:
                variant_image.image.name = path
                variant_image.save()

    def _create_variant_specifications(self, product, variant, specifications_data):
        """创建变体规格"""
        if not specifications_data:
            return

        for index, spec_data in enumerate(specifications_data):
            key = spec_data.get('key') or spec_data.get('spec_key')
            value = spec_data.get('value') or spec_data.get('spec_value')
            if not key or not value:
                continue

            ProductSpecification.objects.create(
                product=product,
                variant=variant,
                spec_key=key,
                spec_value=value,
                sort_order=spec_data.get('sort_order', index),
                is_active=spec_data.get('is_active', True)
            )
    
    def _get_or_create_option_value(self, opt_val_data):
        """获取或创建选项值"""
        option_type = opt_val_data['option_type']
        value = opt_val_data['value']
        color_code = opt_val_data.get('color_code')
        translations = opt_val_data.get('translations', {})
        
        # 获取或创建选项类型
        option, _ = ProductOption.objects.get_or_create(
            option_type=option_type,
            defaults={'name': option_type, 'is_active': True}
        )
        
        # 获取或创建选项值
        option_value, created = ProductOptionValue.objects.get_or_create(
            option=option,
            value=value,
            defaults={'color_code': color_code, 'is_active': True}
        )
        
        # 如果不是新创建的，更新 color_code
        if not created and color_code:
            option_value.color_code = color_code
            option_value.save()
        
        # 创建或更新翻译
        for locale, trans_value in translations.items():
            ProductOptionValueTranslation.objects.update_or_create(
                option_value=option_value,
                locale=locale,
                defaults={'value': trans_value}
            )
        
        return option_value
